package com.haiyou.dc.aggregate.linklist;

import java.util.Arrays;

public class MyArrayList<E> extends MyAbstractList<E> {

    private Object[] elementData;
    private static final int DEFAULT_CAPACITY = 10;


    public MyArrayList(int initialCapacity) {
        this.elementData = new Object[initialCapacity];
    }

    public MyArrayList() {
        this(DEFAULT_CAPACITY);
    }

    @Override
    public int add(E element) {
        ensureCapacity(size + 1);
        elementData[size++] = element;
        return 1;
    }

    @Override
    public int add(int index, E element) {
//        for (int i = size - 1; i >= index; i--) {
//            elementData[i + 1] = elementData[i];
//        }

        rangeCheckForAdd(index);
        ensureCapacity(size + 1);


        System.arraycopy(elementData, index, elementData, index + 1, size - index);
        elementData[index] = element;
        size++;
        return 0;
    }

    private void ensureCapacity(int newCapacity) {
        int oldCapacity = elementData.length;
        if (oldCapacity > newCapacity) {
            return;
        }
        newCapacity = newCapacity + (oldCapacity >> 1);
        Object[] newElements = new Object[newCapacity];
//        for (int i = 0; i < size; i++) {
//            newElements[i] = elementData[i];
//        }
//        elementData = newElements;
        elementData = Arrays.copyOf(elementData, newCapacity);
        System.out.println("oldCapacity=" + oldCapacity + ",newCapacity=" + newCapacity);
    }

    @Override
    public E set(int index, E element) {
        rangeCheck(index);
        E oldIndex = elementData(index);
        elementData[index] = element;
        return oldIndex;
    }


    E elementData(int index) {
        return (E) elementData[index];
    }

    @Override
    public E get(int index) {
        rangeCheck(index);
        return elementData(index);
    }

    @Override
    public void remove(int index) {
        rangeCheck(index);
//        for (int i = index + 1; i < size; i++) {
//            elementData[i - 1] = elementData[i];
//        }
        int numMoved = size - index - 1;
        System.arraycopy(elementData, index + 1, elementData, index, numMoved);
        elementData[--size] = null;
    }

    @Override
    public int indexOf(E element) {
        if (element == null) {
            for (int i = 0; i < size; i++) {
                if (elementData[i] == null) {
                    return i;
                }
            }
        } else {
            for (int i = 0; i < size; i++) {
                if (elementData[i].equals(element)) {
                    return i;
                }
            }
        }
        return ELEMENT_NOT_FOUND;
    }

    @Override
    public void clear() {
        for (int i = 0; i < size; i++) {
            elementData[i] = null;
        }
        size = 0;
    }

    @Override
    public String toString() {
        return "MyArrayList{" +
                "size=" + size +
                ", elementData=" + Arrays.toString(elementData) +
                '}';
    }

}
